package com.xiaohe66.web.domain.birth.value;

import com.xiaohe66.common.util.time.ChineseDate;
import com.xiaohe66.web.integration.value.DayValue;
import com.xiaohe66.web.integration.value.MonthValue;
import com.xiaohe66.web.integration.value.YearValue;
import lombok.EqualsAndHashCode;
import lombok.Getter;

import java.time.LocalDate;

/**
 * @author xiaohe
 * @since 2023.07.12 15:58
 */
@Getter
@EqualsAndHashCode
public class BirthdayDate {

    private final BirthdayValue birthdayValue;
    private YearValue year;

    public BirthdayDate(BirthdayValue birthdayValue) {
        this(birthdayValue, null);
    }

    public BirthdayDate(BirthdayValue birthdayValue, YearValue year) {
        this.birthdayValue = birthdayValue;
        this.year = year;
    }

    public BirthdayDate(BirthdayType birthdayType, MonthValue month, DayValue day) {
        this(new BirthdayValue(birthdayType, month, day));
    }

    public BirthdayDate(BirthdayType birthdayType, MonthValue month, DayValue day, YearValue year) {
        this(new BirthdayValue(birthdayType, month, day), year);
    }

    public BirthdayDate nextBirthday() {
        return birthdayValue.nextBirthday();
    }

    public LocalDate toDate() {
        if (year == null) {
            throw new IllegalStateException("not set year, cannot toDate");
        }

        return birthdayValue.toDate(year.getValue());
    }

    public static BirthdayDate valueOf(ChineseDate chineseDate) {
        YearValue year = YearValue.valueOf(chineseDate.getYear());
        MonthValue month = MonthValue.valueOf(chineseDate.getMonth());
        DayValue day = DayValue.valueOf(chineseDate.getDay());

        return new BirthdayDate(BirthdayType.CHINESE, month, day, year);
    }

    public static BirthdayDate valueOf(LocalDate localDate) {
        YearValue year = YearValue.valueOf(localDate.getYear());
        MonthValue month = MonthValue.valueOf(localDate.getMonthValue());
        DayValue day = DayValue.valueOf(localDate.getDayOfMonth());

        return new BirthdayDate(BirthdayType.GREGORIAN, month, day, year);
    }

    public static BirthdayDate valueOf(int type, int y, int m, int d) {

        BirthdayType birthdayType = BirthdayType.valueOf(type);

        YearValue year = YearValue.valueOf(y);
        MonthValue month = MonthValue.valueOf(m);
        DayValue day = DayValue.valueOf(d);

        return new BirthdayDate(birthdayType, month, day, year);
    }

    @Override
    public String toString() {

        return String.format("BirthdayDate(%s, %s-%s-%s)" ,
                birthdayValue.getType().name(),
                year == null ? "?" : year.getValue(),
                birthdayValue.getMonth().getValue(),
                birthdayValue.getDay().getValue());
    }
}
